package interfaces.subpanel.cargardatos.gui;

import interfaces.mainpanel.gui.TesisMainGUI;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import model.GenericScenarie;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import renderers.TextAreaRenderer;
import utils.AttributesEnumUtils;
import utils.ImagenesUtils;
import utils.POIUtil;

import com.google.common.collect.Maps;

import enumerations.AttributesEnum;

public class LoadDataTableRender extends JPanel {

	private static final long serialVersionUID = 1L;

	private static final int ATTRIBUTE_COLUMN_WIDTH = 150;

	private static final short COLUMN_ATTRIBUTE = 0;

	private static final short COLUMN_USE_CASE = 1;

	private static final short COLUMN_PROJECT_ID = 2;

	private MyTableModel model;

	private JTable table;

	private boolean selectable;

	private boolean showComboCellEditor;

	private JLabel rows = new JLabel("0");

	private TesisMainGUI mainGUI;

	public LoadDataTableRender(TesisMainGUI mainGUI, boolean selectable, boolean showComboCellEditor) {

		super(new BorderLayout(0, 5));

		this.mainGUI = mainGUI;

		this.selectable = selectable;
		this.showComboCellEditor = showComboCellEditor;
		this.model = new MyTableModel();
		this.table = new JTable(this.model);
		this.table.setFillsViewportHeight(true);
		this.table.setPreferredScrollableViewportSize(new Dimension(500, 70));
		this.table.getTableHeader().setPreferredSize(new Dimension(10, 27));

		if (this.selectable)
			this.table
					.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		else
			this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		TableColumnModel cmodel = this.table.getColumnModel();
		cmodel.getColumn(1).setCellRenderer(new TextAreaRenderer());
		JScrollPane scrollPane = new JScrollPane(this.table);
		initColumnSizes();
		setUpAttributeColumn(this.table.getColumnModel().getColumn(0));
		JPanel rowsPanel = new JPanel();
		rowsPanel.add(new JLabel("Rows: "));
		rowsPanel.add(this.rows);
		add(scrollPane, BorderLayout.CENTER);
		add(rowsPanel, BorderLayout.PAGE_END);
	}

	private void initColumnSizes() {

		this.table.getColumnModel().getColumn(0)
				.setMinWidth(ATTRIBUTE_COLUMN_WIDTH);
		this.table.getColumnModel().getColumn(0)
				.setMaxWidth(ATTRIBUTE_COLUMN_WIDTH);
	}

	public void setUpAttributeColumn(TableColumn attibuteColumn) {

		if (this.showComboCellEditor) {
			JComboBox comboBox = new JComboBox(new MyComboBoxModel());
			attibuteColumn.setCellEditor(new DefaultCellEditor(comboBox));
			DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
			renderer.setToolTipText("Click to edit the attribute.");
			attibuteColumn.setCellRenderer(renderer);
		}
	}

	public void loadTableWithFileContent(File file) {

		try {
			POIFSFileSystem document = new POIFSFileSystem(new FileInputStream(
					file));
			HSSFWorkbook book = new HSSFWorkbook(document);
			HSSFSheet sheet = book.getSheetAt(0);
			List<GenericScenarie> scenaries = new ArrayList<GenericScenarie>();
			Map<String, GenericScenarie> scenariesById = Maps.newHashMap();
			for (int i = 1; i <= sheet.getLastRowNum(); i++) {
				HSSFRow row = sheet.getRow(i);
				if (row != null) {
					String attributeName = POIUtil.getStringValue(row
							.getCell(COLUMN_ATTRIBUTE));
					if (attributeName == null)
						attributeName = "";
					String scenarie = POIUtil.getStringValue(row
							.getCell(COLUMN_USE_CASE));
					String projectId = POIUtil.getStringValue(row
							.getCell(COLUMN_PROJECT_ID));
					AttributesEnum attributeEnum = AttributesEnumUtils
							.getAttributesEnumFromValue(attributeName);
					if (attributeEnum != null
							&& StringUtils.isNotBlank(scenarie)
							&& projectId != null) {
						GenericScenarie genericScenarie = new GenericScenarie(
								String.valueOf(i), attributeEnum, scenarie,
								projectId);
						scenaries.add(genericScenarie);
						scenariesById.put(String.valueOf(i), genericScenarie);
					}
				}
			}
			this.model.addAllGenericScenaries(scenaries);
			this.mainGUI.getLoadDataSetGUI().setScenariesById(scenariesById);
		} catch (IOException e) {
			JOptionPane
					.showMessageDialog(this,
							"ERROR: Problem while loading the data. The problem was: "
									+ e.getMessage() + ".", "ERROR!",
							JOptionPane.ERROR_MESSAGE, ImagenesUtils
									.createImageIcon(this.getClass(),
											"/stop.png"));
		}
	}

	public List<GenericScenarie> removeIndexes(int[] genericScenariesIndexes) {
		return this.model.removeIndexes(genericScenariesIndexes);
	}

	public int[] getSelectedRows() {
		return this.table.getSelectedRows();
	}

	public int dataSize() {
		return this.model.dataSize();
	}

	public boolean isEmpty() {
		return this.model.isEmpty();
	}

	public boolean isNotEmpty() {
		return this.model.isNotEmpty();
	}

	public GenericScenarie getGenericScenarie(int index) {
		return this.model.getGenericScenarie(index);
	}

	public void removeGenericScenarie(int index) {
		this.model.removeGenericScenarie(index);
	}

	public void addAllGenericScenaries(List<GenericScenarie> genericScenaries) {
		this.model.addAllGenericScenaries(genericScenaries);
	}

	public void removeAllGenericScenaries() {
		this.model.removeAllGenericScenaries();
	}

	public List<GenericScenarie> getAllGenericScenaries() {
		return this.model.getAllGenericScenaries();
	}

	public JLabel getRows() {
		return rows;
	}

	public void setRowsQuantity(int rows) {
		this.rows.setText(String.valueOf(rows));
	}

}
